/**
 * 微信小程序请求库
 * 支持自动授权、请求拦截、响应处理等功能
 */

// 配置项
const config = {
	// API基础地址
	baseURL: 'https://your-api-domain.com/api',
	// 请求超时时间（毫秒）
	timeout: 10000,
	// 是否自动处理授权
	autoAuth: true,
	// 授权失败重试次数
	authRetryCount: 1,
	// 请求头
	headers: {
		'Content-Type': 'application/json'
	}
};

// 请求队列，用于处理授权过程中的请求
let requestQueue = [];
// 是否正在授权
let isAuthorizing = false;
// 授权重试次数
let authRetryTimes = 0;

/**
 * 显示加载提示
 * @param {string} title 提示文字
 */
const showLoading = (title = '加载中...') => {
	wx.showLoading({
		title,
		mask: true
	});
};

/**
 * 隐藏加载提示
 */
const hideLoading = () => {
	wx.hideLoading();
};

/**
 * 显示错误提示
 * @param {string} message 错误信息
 */
const showError = (message) => {
	wx.showToast({
		title: message,
		icon: 'error',
		duration: 2000
	});
};

/**
 * 获取本地存储的token
 * @returns {string|null}
 */
const getToken = () => {
	return wx.getStorageSync('token') || null;
};

/**
 * 保存token到本地存储
 * @param {string} token
 */
const setToken = (token) => {
	wx.setStorageSync('token', token);
};

/**
 * 清除本地存储的token
 */
const clearToken = () => {
	wx.removeStorageSync('token');
};

/**
 * 微信授权登录（静默授权）
 * @returns {Promise<Object>}
 */
const wxLogin = () => {
	return new Promise((resolve, reject) => {
		wx.login({
			success: (res) => {
				if (res.code) {
					resolve(res);
				} else {
					reject(new Error('微信登录失败'));
				}
			},
			fail: (err) => {
				reject(err);
			}
		});
	});
};

/**
 * 执行授权流程（静默授权）
 * @returns {Promise<Object>}
 */
const performAuth = async () => {
	try {
		isAuthorizing = true;

		// 获取微信登录code（静默授权）
		const loginRes = await wxLogin();

		// 发送授权请求到服务器
		const authData = {
			code: loginRes.code
		};

		const authRes = await new Promise((resolve, reject) => {
			wx.request({
				url: `${config.baseURL}/v1/user/init`,
				method: 'POST',
				data: authData,
				header: {
					'Content-Type': 'application/json'
				},
				timeout: config.timeout,
				success: (res) => {
					resolve(res);
				},
				fail: (err) => {
					reject(err);
				}
			});
		});
		

		if (authRes.statusCode == 200 && (authRes.data.code === 1 || authRes.data.code === 20000)) {
			const { token, user } = authRes.data.data;

			setToken(token);

			// 保存用户信息
			if (user) {
				wx.setStorageSync('userInfo', user);
			}

			return authRes.data;
		} else {
			throw new Error(authRes.data.msg || authRes.data.message || '授权失败');
		}

	} catch (error) {
		console.error('授权失败:', error);
		throw error;
	} finally {
		isAuthorizing = false;
	}
};

/**
 * 处理授权失败的情况
 * @param {Function} requestFn 原始请求函数
 * @param {Object} options 请求选项
 * @returns {Promise<Object>}
 */
const handleAuthFailure = async (requestFn, options) => {
	if (!config.autoAuth || authRetryTimes >= config.authRetryCount) {
		// 超过重试次数或禁用自动授权，直接抛出错误
		clearToken();
		throw new Error('授权失败，请重新登录');
	}

	authRetryTimes++;

	try {
		// 执行授权
		await performAuth();

		// 授权成功后，重新执行原始请求
		return await requestFn(options);

	} catch (error) {
		// 授权失败，清除token并抛出错误
		clearToken();
		throw error;
	}
};

/**
 * 处理请求队列
 */
const processRequestQueue = () => {
	while (requestQueue.length > 0) {
		const { resolve, reject, requestFn, options } = requestQueue.shift();
		requestFn(options).then(resolve).catch(reject);
	}
};

/**
 * 核心请求函数
 * @param {Object} options 请求选项
 * @returns {Promise<Object>}
 */
const request = async (options) => {
	const {
		url,
		method = 'GET',
		data = {},
		header = {},
		showLoading: showLoadingFlag = false,
		needAuth = true,
		showErrorInfo,
		...otherOptions
	} = options;

	// 显示加载提示
	if (showLoadingFlag) {
		showLoading();
	}

	try {
		// 构建请求头
		const requestHeader = {
			...config.headers,
			...header
		};

		// 如果需要授权，添加token
		if (needAuth) {
			const token = getToken();
			if (token) {
				requestHeader.Authorization = `Bearer ${token}`;
			}
		}

		// 构建完整URL
		const fullUrl = url.startsWith('http') ? url : `${config.baseURL}${url}`;

		// 发送请求
		const result = await new Promise((resolve, reject) => {
			wx.request({
				url: fullUrl,
				method: method.toUpperCase(),
				data,
				header: requestHeader,
				timeout: config.timeout,
				...otherOptions,
				success: (res) => {
					resolve(res);
				},
				fail: (err) => {
					reject(err);
				}
			});
		});

		// 处理响应
		if (result.statusCode === 200) {
			const responseData = result.data;

			// 检查业务状态码 - 支持多种成功状态码
			if (responseData.code === 1 || responseData.code === 20000) {
				return responseData;
			} else if (responseData.code === 401 && needAuth) {
				// 授权失败，尝试重新授权
				return await handleAuthFailure(request, options);
			} else {
				// 其他业务错误
				throw new Error(responseData.msg || responseData.message || '请求失败');
			}
		} else if (result.statusCode === 401 && needAuth) {
			// HTTP 401 未授权
			return await handleAuthFailure(request, options);
		} else {
			// 其他HTTP错误
			throw new Error(`HTTP ${result.statusCode}: ${result.errMsg || '请求失败'}`);
		}

	} catch (error) {

		// 如果是网络错误，显示提示
		if (error.errMsg && error.errMsg.includes('timeout')) {
			showError('请求超时，请检查网络连接');
		} else if (error.errMsg && error.errMsg.includes('fail')) {
			showError('网络连接失败，请检查网络设置');
		} else {
			if(showErrorInfo){
				showError(error.message || '请求失败');
			}
		}

		throw error;
	} finally {
		// 隐藏加载提示
		if (showLoadingFlag) {
			hideLoading();
		}
	}
};

/**
 * 带授权的请求函数
 * @param {Object} options 请求选项
 * @returns {Promise<Object>}
 */
const authRequest = async (options) => {
	// 如果正在授权，将请求加入队列
	if (isAuthorizing) {
		return new Promise((resolve, reject) => {
			requestQueue.push({ resolve, reject, requestFn: authRequest, options });
		});
	}

	// 检查是否需要授权
	const token = getToken();
	if (!token) {
		// 没有有效token，先进行授权
		try {
			await performAuth();
			// 授权成功后处理队列中的请求
			processRequestQueue();
		} catch (error) {
			// 授权失败，清空队列
			requestQueue.forEach(({ reject }) => reject(error));
			requestQueue = [];
			throw error;
		}
	}

	return request(options);
};

/**
 * GET请求
 * @param {string} url 请求地址
 * @param {Object} options 其他选项
 * @returns {Promise<Object>}
 */
const get = (url, options = {}) => {
	return request({
		url,
		method: 'GET',
		...options
	});
};

/**
 * POST请求
 * @param {string} url 请求地址
 * @param {Object} data 请求数据
 * @param {Object} options 其他选项
 * @returns {Promise<Object>}
 */
const post = (url, data = {}, options = {}) => {
	return request({
		url,
		method: 'POST',
		data,
		...options
	});
};

/**
 * 带授权的GET请求
 * @param {string} url 请求地址
 * @param {Object} options 其他选项
 * @returns {Promise<Object>}
 */
const authGet = (url, options = {}) => {
	return authRequest({
		url,
		method: 'GET',
		...options
	});
};

/**
 * 带授权的POST请求
 * @param {string} url 请求地址
 * @param {Object} data 请求数据
 * @param {Object} options 其他选项
 * @returns {Promise<Object>}
 */
const authPost = (url, data = {}, options = {}) => {
	return authRequest({
		url,
		method: 'POST',
		data,
		...options
	});
};

/**
 * 更新配置
 * @param {Object} newConfig 新配置
 */
const updateConfig = (newConfig) => {
	Object.assign(config, newConfig);
};

/**
 * 重置授权状态
 */
const resetAuth = () => {
	clearToken();
	authRetryTimes = 0;
	isAuthorizing = false;
	requestQueue = [];
};

// 导出模块
module.exports = {
	// 核心方法
	request,
	authRequest,

	// 基本方法
	get,
	post,
	authGet,
	authPost,

	// 工具方法
	getToken,
	setToken,
	clearToken,
	updateConfig,
	resetAuth,

	// 配置
	config
};
